<?php

class Admin_Model_TreeNode {
	public $Id;
	public $ParentId;
	public $LeftId;
	public $RightId;
	public $Level;
	public $Name;
	public $LayoutId;
	public $Title;
	public $MetaDescription;
	public $MetaKeywords;
	public $XML; 
	public $HTML;
	public $CfgId;
	public $URL;
	public $InMenu;
	public $MenuTitle;
	public $ChangeFreq;
	public $Priority;
	public $Tag;
    
    /*
     * Если истина, то идет кеширование. , т. е. надо сериалайзить нужные при кешировании поля
     */
    protected $_Cache;
    
	public function __construct($options = null)
    {
    	if ($options instanceof Admin_Model_TreeNode)
    	{
    		$options = $options->toArray();
    		$this->setOptions($options);
    		$this->unpack();
    	}
        else if (is_array($options)) {
            $this->setOptions($options);
            //$this->unpack();
        }
        $this->_Cache = false;
    }
    
    function isParentDepended(){return false;}
    
    public function __sleep(){
        if (!$this->_Cache)
            return array();
		return array('Id','ParentId','LeftId','RightId','Level',
			'Name','LayoutId','Title','MetaDescription','MetaKeywords','XML' //,'HTML'
		,'CfgId','URL','InMenu','MenuTitle','Tag');
	}
    
    public function setCache($value){
        $this->_Cache = $value; return $this;
    }
    
    protected function _checkXml($xml){
        throw new Exception('This method depricated');
    }
    public function serialize(){return serialize($this);}

    public function pack(){
        throw new Zend_Exception("This method depricated");
    }
    
	public function unpack(){
        throw new Zend_Exception("This method depricated");
	}
    
	public static function getFields(){
		return get_class_vars('Admin_Model_TreeNode');
	}
	
	public function setOptions(array $options){
        $methods = get_class_methods($this);
        foreach ($options as $key => $value) {
            $method = 'set' . ucfirst($key);
            if (in_array($method, $methods)) {
                $this->$method($value);
            }
        }
        return $this;
    }
    
    /**
     * Преобразовывает поля объекта в ассоциативный массив.
     * 
     * @param bool | array $onlyFields	если истина - в массив преобразуются только поля класса Admin_Model_TreeNode, 
     * 									если ложь - все поля данного экземпляра (наследника от Admin_Model_TreeNode.
     * 									Если ассоциативный массив, то массив будет содержать только те поля, которые указаны
     * 									в качестве ключей в массиве $onlyFields
     * @return array
     */
    public function toArray($onlyFields=false){
    	if ($onlyFields===true)
    		$vars = get_class_vars('Admin_Model_TreeNode');
    	elseif ($onlyFields===false)
    		$vars = get_class_vars(get_class($this));
    	elseif (is_array($onlyFields))
    		$vars = array_intersect_key(get_class_vars(get_class($this)),$onlyFields); 
        unset($vars['_Cache']);
        foreach ($vars as $var=>$value)
        {
        		$vars[$var] = $this->$var;
        }
        return $vars;
    }
	public function __set($name, $value)
    {
        $method = 'set' . $name;
        if (('mapper' == $name) || !method_exists($this, $method)) {
            throw new Exception('Invalid property');
        }
        $this->$method($value);
    }

    public function __get($name)
    {
        $method = 'get' . $name;
        if (('mapper' == $name) || !method_exists($this, $method)) {
            throw new Exception('Invalid property');
        }
        return $this->$method();
    }

	public function setId($id) {
		$this->Id = $id;
		return $this;
	}
	
	public function setInMenu($inMenu){
		$this->InMenu = $inMenu;
		return $this;
	}
	
	public function setName($name) {
		$this->Name = $name;
		return $this;
	}
	public function setLayoutId($value){
		$this->LayoutId = $value;
		return $this;
	}
	
	public function setTitle($title)
	{
		$this->Title = $title;
		return $this;
	}
	
	public function setMetaKeywords($meta)
	{
		$this->MetaKeywords = $meta;
		return $this;
	}
	
	public function setMetaDescription($meta)
	{
		$this->MetaDescription = $meta;
		return $this;
	}
	
	public function setHTML($html)
	{
		$this->HTML = $html;
		return $this;
	}
	
	public function setCfgId($CfgId)
	{
		$this->CfgId = $CfgId;
		return $this;
	}
	public function setXML($xml)
	{
		$this->XML = $xml;
		return $this;
	}
	public function setRightId($rightId)
	{
		$this->RightId = $rightId;
		return $this;
	}
	public function setLeftId($leftId)
	{
		$this->LeftId = $leftId;
		return $this;
	}
	public function setLevel($level)
	{
		$this->Level = $level;
		return $this;
	}
	
	public function setParentId($parentId)
	{
		$this->ParentId = $parentId;
		return $this;
	}
	public function setURL($url)
	{
		$this->URL = $url;
		return $this;
	}
	public function setMenuTitle($value){
		$this->MenuTitle = $value;
		return $this;
	}
	
	public function setChangeFreq($value){
		$this->ChangeFreq = $value;
		return $this;
	}
	public function setPriority($value){
		$this->Priority = $value;
		return $this;
	}
	public function setTag($value){
		$this->Tag = $value;
		return $this;
	}
	
	public function getInMenu(){
		return $this->InMenu;
	}
	
	public function getURL(){
		return $this->URL;
	}
	
	public function getId() {
		return $this->Id;
	}

	public function getName() {
		return $this->Name;
	}
	
	public function getLayoutId(){
		return $this->LayoutId;
	}
	
	public function getTitle() {
		return $this->Title;
	}
	
	public function getMetaKeywords() {
		return $this->MetaKeywords;
	}
	
	public function getMetaDescription() {
		return $this->MetaDescription;
	}
	
	public function getHTML() {
		return $this->HTML;
	}
	
	public function getCfgId()
	{
		return $this->CfgId;
	}
	public function getXML()
	{
		return $this->XML;
	}
	public function getRightId()
	{
		return $this->RightId;
	}
	public function getLeftId()
	{
		return $this->LeftId;
	}
	public function getLevel()
	{
		return $this->Level;
	}
	public function getParentId()
	{
		return $this->ParentId;
	}
	
	public function getMenuTitle(){
		return $this->MenuTitle;
	}
	
	public function getChangeFreq(){
		return $this->ChangeFreq;
	}
	public function getPriority(){
		return $this->Priority;
	}
	public function getTag(){
		return $this->Tag;
	}
	
	public function render($options=null){
		return $this->replaceTags(
				$this->prepareLinks(
						$this->getHTML()
					)
				);
	}
	
	public function replaceTags($text)
	{
		$text = str_ireplace('<br>', '<br/>', $text);
		$text = str_ireplace('<b>', '<strong>', $text);
		$text = str_ireplace('</b>', '</strong>', $text);
		$text = str_ireplace('<nobr>', '<span class="nobr">', $text);
		$text = str_ireplace('</nobr>', '</span>', $text);
		return $text;
	}
	
	public static function prepareLinks($text)
    {
    	$ids = Admin_Model_TreeNode::_getLinkedIds($text,"hrefid", array());
		$ids = Admin_Model_TreeNode::_getLinkedIds($text,"titleid", $ids);
		if (count($ids)==0)
			return $text;
		$mapper = new Admin_Model_TreeNodeMapper();
		$t = $mapper->getDbTable();
		$result = $t->fetchAll(
			$t->select()	->from($t,array("URL", "Title", "Id"))
							->where(
								implode($ids, " OR ")
							)
							->order("Id DESC")
		);
		foreach($result as $r){
			if (isset($ids[$r->Id])){
				$text = str_replace("hrefid".$r->Id, $r->URL, $text);
				$text = str_replace("titleid".$r->Id, $r->Title, $text);
			}
			else
				throw new Zend_Exception("Не найден идентификатор ".$r->Id);
		}
		return $text;
    }
	
	protected static function _getLinkedIds($text, $tplVarNAme, $ids){
    	$offset = 0;
    	do{
    		$p = strpos($text,$tplVarNAme,$offset);
    		if ($p===false) break;
    		$p+=strlen($tplVarNAme);
    		$id = "";
    		while(is_numeric($text{$p})){
    			$id.=$text{$p};
    			$p++;
    		}
			/*if ($id!="")
				$ids[] = $id;*/
    		if (($id!="") && !isset($ids[$id]))
				$ids[$id] = 'Id='.$id;
    		$offset = $p;
    	}while(true);
    	return $ids;
	}
    /*
     * Клонирует имеющиеся картинки
     * @param $thumbID - int идентификатор варианта картинки для preview
     * @param $imagesHolderName - string название переменной в классе-наследнике, которая содержит массив картинок
     */
    protected function _cloneImages($imagesHolderName = "Images"){
        if (null!=$this->$imagesHolderName){
            $oldArr = $this->$imagesHolderName;
            $arr = array();
            for($i=0;$i<count($oldArr);$i++){
                $arr[] = clone $oldArr[$i];
            }
            $this->$imagesHolderName = $arr;
        }
    }
}
?>